home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / dfpp01.zip / TEXTBOX.CPP < prev    next >
C/C++ Source or Header  |  1992-11-11  |  9KB  |  396 lines

  1. // ------------- textbox.cpp
  2.  
  3. #include "desktop.h"
  4. #include "textbox.h"
  5. #include "scrolbar.h"
  6.  
  7. // ----------- common constructor code
  8. void TextBox::OpenWindow()
  9. {
  10.     windowtype = TextboxWindow;
  11.     if (windowstate == CLOSED)
  12.         Control::OpenWindow();
  13.     text = NULL;
  14.     bufflen = InitialBufferSize;
  15.     hscrollbar = vscrollbar = NULL;
  16.     TextPointers = NULL;
  17.     ClearText();
  18.     SetColors();
  19. }
  20.  
  21. void TextBox::CloseWindow()
  22. {
  23.     ClearText();
  24.     if (hscrollbar != NULL)
  25.         delete hscrollbar;
  26.     if (vscrollbar != NULL)
  27.         delete vscrollbar;
  28.     Control::CloseWindow();
  29. }
  30.  
  31.  
  32. // ------ show the textbox
  33. void TextBox::Show()
  34. {
  35.     if ((attrib & HSCROLLBAR) && hscrollbar == NULL)    {
  36.         hscrollbar = new ScrollBar(HORIZONTAL, this);
  37.         hscrollbar->SetAttribute(FRAMEWND);
  38.     }
  39.     if ((attrib & VSCROLLBAR) && vscrollbar == NULL)    {
  40.         vscrollbar = new ScrollBar(VERTICAL, this);
  41.         vscrollbar->SetAttribute(FRAMEWND);
  42.     }
  43.     Control::Show();
  44. }
  45.  
  46. // ------------ build the text line pointers
  47. void TextBox::BuildTextPointers()
  48. {
  49.     textwidth = wlines = 0;
  50.     // ---- count the lines of text
  51.     char *cp1, *cp = *text;
  52.     while (*cp)    {
  53.         wlines++;
  54.         while (*cp && *cp != '\n')
  55.             cp++;
  56.         if (*cp)
  57.             cp++;
  58.     }
  59.     // ----- build the pointer array
  60.     delete TextPointers;
  61.     TextPointers = new unsigned int[wlines];
  62.     unsigned int off;
  63.     cp = *text;
  64.     wlines = 0;
  65.     while (*cp)    {
  66.         off = (unsigned int) (cp - *text);
  67.         *(TextPointers + wlines++) = off;
  68.         cp1 = cp;
  69.         while (*cp && *cp != '\n')
  70.             cp++;
  71.         textwidth = max(textwidth, (unsigned int) (cp - cp1));
  72.         if (*cp)
  73.             cp++;
  74.     }
  75. }
  76.  
  77. // --------- add a line of text to the textbox
  78. void TextBox::AddText(char *txt)
  79. {
  80.     String tx(txt);
  81.     int len = tx.Strlen();
  82.     if (tx[len-1] != '\n')
  83.         textlen++;
  84.     textlen += len;
  85.     if (text == NULL)
  86.         text = new String(bufflen);
  87.     if (textlen > text->StrBufLen())
  88.         text->ChangeLength(max(bufflen, textlen));
  89.     *text += tx;
  90.     if (*text[len-1] != '\n')
  91.         *text += String("\n");
  92.     BuildTextPointers();
  93. }
  94.  
  95. // --------- set the textbox's text buffer to new text
  96. void TextBox::SetText(char *txt)
  97. {
  98.     ClearText();
  99.     AddText(txt);
  100. }
  101.  
  102. // ------ set the length of the text buffer
  103. void TextBox::SetTextLength(unsigned int len)
  104. {
  105.     if (text != NULL)
  106.         text->ChangeLength(len);
  107.     bufflen = len;
  108. }
  109.  
  110. // --------- clear the text from the textbox
  111. void TextBox::ClearText()
  112. {
  113.     if (text != NULL)
  114.         delete text;
  115.     textlen = 0;
  116.     wlines = 0;
  117.     textwidth = 0;
  118.     wtop = wleft = 0;
  119.     ClearTextBlock();
  120.     if (TextPointers != NULL)
  121.         delete TextPointers;
  122. }
  123.  
  124. // -------- set the fg/bg colors for the window 
  125. void TextBox::SetColors()
  126. {
  127.     colors.fg = BLACK;
  128.     colors.bg = LIGHTGRAY;
  129.     colors.sfg = LIGHTGRAY;
  130.     colors.sbg = BLACK;
  131.     colors.ffg = BLACK;
  132.     colors.fbg = LIGHTGRAY;
  133.     colors.hfg = BLACK;
  134.     colors.hbg = LIGHTGRAY;
  135.     shortcutfg = BLUE;
  136. }
  137.  
  138. // ------- extract a text line
  139. String TextBox::ExtractTextLine(int lno)
  140. {
  141.     char *lp = TextLine(lno);
  142.     int offset = lp - (char *) *text;
  143.     for (int len = 0; *(lp+len) && *(lp+len) != '\n'; len++)
  144.         ;
  145.     return text->mid(len, offset);
  146. }
  147.  
  148. // ---- display a line with a shortcut key character
  149. void TextBox::WriteShortcutLine(int lno, int fg, int bg)
  150. {
  151.     String sc = ExtractTextLine(lno);
  152.     int x = sc.Strlen();
  153.     int y = lno-wtop;
  154.     x -= DisplayShortcutField(sc, 0, y, fg, bg);
  155.     // --------- pad the line
  156.     int wd = ClientWidth() - x;
  157.     if (wd > 0)
  158.         WriteClientString(String(wd, ' '), x, y, fg, bg);
  159. }
  160.  
  161. // ---- display a shortcut field character
  162. int TextBox::DisplayShortcutField(String sc, int x, int y,
  163.                                                 int fg, int bg)
  164. {
  165.     int scs = 0;
  166.     int off = sc.FindChar(SHORTCUTCHAR);
  167.     if (off != -1)    {
  168.         scs++;
  169.         if (off != 0)    {
  170.             String ls = sc.left(off);
  171.             WriteClientString(ls, x, y, fg, bg);
  172.         }
  173.         WriteClientChar(sc[off+1], x+off, y, shortcutfg, bg);
  174.         int len = sc.Strlen()-off-2;
  175.         if (len > 0)    {
  176.             String rs = sc.right(len);
  177.             scs += DisplayShortcutField(rs, x+off+1, y, fg, bg);
  178.         }
  179.     }
  180.     else
  181.         WriteClientString(sc, x, y, fg, bg);
  182.     return scs;
  183. }
  184.  
  185. // ------- write a text line to the textbox
  186. void TextBox::WriteTextLine(int lno, int fg, int bg)
  187. {
  188.     if (lno < wtop || lno >= wtop + ClientHeight())
  189.         return;
  190.     int wd = ClientWidth();
  191.     String tl = ExtractTextLine(lno);
  192.     String ln = tl.mid(wd, wleft);
  193.     int dif = wd-ln.Strlen();
  194.     if (dif > 0)
  195.         ln = ln + String(dif, ' ');    // pad the line with spaces
  196.     // ----- display the line
  197.     WriteClientString(ln, 0, lno-wtop, fg, bg);
  198. }
  199.  
  200. // ---------- paint the textbox
  201. void TextBox::Paint()
  202. {
  203.     if (text == NULL)
  204.         Control::Paint();
  205.     else    {
  206.         int ht = ClientHeight();
  207.         int wd = ClientWidth();
  208.         int fg = colors.fg;
  209.         int bg = colors.bg;
  210.         for (int i = 0; i < min(wlines-wtop,ht); i++)
  211.             WriteTextLine(wtop+i, fg, bg);
  212.         // ---- pad the bottom lines in the window
  213.         String line(wd, ' ');
  214.         while (i < ht)
  215.             WriteClientString(line, 0, i++, fg, bg);
  216.         if (resetscrollbox)
  217.             SetScrollBoxes();
  218.         resetscrollbox = False;
  219.     }
  220. }
  221.  
  222. // ------ process a textbox keystroke
  223. void TextBox::Keyboard(int key)
  224. {
  225.     switch (key)    {
  226.         case UP:
  227.             if (ClientTop() == ClientBottom())
  228.                 break;
  229.             ScrollDown();
  230.             return;
  231.         case DN:
  232.             if (ClientTop() == ClientBottom())
  233.                 break;
  234.             ScrollUp();
  235.             return;
  236.         case FWD:
  237.             ScrollLeft();
  238.             return;
  239.         case BS:
  240.             ScrollRight();
  241.             return;
  242.         case PGUP:
  243.             PageUp();
  244.             return;
  245.         case PGDN:
  246.             PageDown();
  247.             return;
  248.         case CTRL_PGUP:
  249.             PageLeft();
  250.             return;
  251.         case CTRL_PGDN:
  252.             PageRight();
  253.             return;
  254.         case HOME:
  255.             Home();
  256.             return;
  257.         case END:
  258.             End();
  259.             return;
  260.         default:
  261.             break;
  262.     }
  263.     Control::Keyboard(key);
  264. }
  265.  
  266. // ------- scroll up one line
  267. void TextBox::ScrollUp()
  268. {
  269.     if (wtop < wlines-1)    {
  270.         int fg = colors.fg;
  271.         int bg = colors.bg;
  272.         desktop.screen().Scroll(ClientRect(), 1, fg, bg);
  273.         wtop++;
  274.         int ln = wtop+ClientHeight()-1;
  275.         if (ln < wlines)
  276.             WriteTextLine(ln, fg, bg);
  277.         SetScrollBoxes();
  278.     }
  279. }
  280.  
  281. // ------- scroll down one line
  282. void TextBox::ScrollDown()
  283. {
  284.     if (wtop)    {
  285.         int fg = colors.fg;
  286.         int bg = colors.bg;
  287.         desktop.screen().Scroll(ClientRect(), 0, fg, bg);
  288.         --wtop;
  289.         WriteTextLine(wtop, fg, bg);
  290.         SetScrollBoxes();
  291.     }
  292. }
  293.  
  294. // ------- scroll left one character
  295. void TextBox::ScrollLeft()
  296. {
  297.     if (wleft < textwidth-1)
  298.         wleft++;
  299.     Paint();
  300. }
  301.  
  302. // ------- scroll right one character
  303. void TextBox::ScrollRight()
  304. {
  305.     if (wleft > 0)
  306.         --wleft;
  307.     Paint();
  308. }
  309.  
  310. // ------- page up one screenfull
  311. void TextBox::PageUp()
  312. {
  313.     if (wtop)    {
  314.         wtop -= ClientHeight();
  315.         if (wtop < 0)
  316.             wtop = 0;
  317.         resetscrollbox = True;
  318.         Paint();
  319.     }
  320. }
  321.  
  322. // ------- page down one screenfull
  323. void TextBox::PageDown()
  324. {
  325.     if (wtop < wlines-1)    {
  326.         wtop += ClientHeight();
  327.         if (wlines < wtop)
  328.             wtop = wlines-1;
  329.         resetscrollbox = True;
  330.         Paint();
  331.     }
  332. }
  333.  
  334. // ------- page right one screenwidth
  335. void TextBox::PageRight()
  336. {
  337.     if (wleft < textwidth-1)    {
  338.         wleft += ClientWidth();
  339.         if (textwidth < wleft)
  340.             wleft = textwidth-1;
  341.         resetscrollbox = True;
  342.         Paint();
  343.     }
  344. }
  345.  
  346. // ------- page left one screenwidth
  347. void TextBox::PageLeft()
  348. {
  349.     if (wleft)    {
  350.         wleft -= ClientWidth();
  351.         if (wleft < 0)
  352.             wleft = 0;
  353.         resetscrollbox = True;
  354.         Paint();
  355.     }
  356. }
  357.  
  358. // ----- move to the first line of the textbox
  359. void TextBox::Home()
  360. {
  361.     wtop = 0;
  362.     Paint();
  363. }
  364.  
  365. // ----- move to the last line of the textbox
  366. void TextBox::End()
  367. {
  368.     wtop = wlines-ClientHeight();
  369.     if (wtop < 0)
  370.         wtop = 0;
  371.     Paint();
  372. }
  373.  
  374. // ----- position the scroll boxes
  375. void TextBox::SetScrollBoxes()
  376. {
  377.     if (vscrollbar != NULL)
  378.         vscrollbar->TextPosition(wlines ? (wtop*100)/wlines : 0);
  379.     if (hscrollbar != NULL)
  380.         hscrollbar->TextPosition(textwidth ? (wleft*100)/textwidth : 0);
  381. }
  382.  
  383. // ---- compute the horizontal page position
  384. void TextBox::HorizontalPagePosition(int pct)
  385. {
  386.     wleft = (textwidth * pct) / 100;
  387.     Paint();
  388. }
  389.  
  390. // ---- compute the vertical page position
  391. void TextBox::VerticalPagePosition(int pct)
  392. {
  393.     wtop = (wlines * pct) / 100;
  394.     Paint();
  395. }
  396.